package ldap

import (
	"errors"
	"fmt"
	"github.com/go-ldap/ldap/v3"
	"log"
	"oauth2/config"
)

var conn *ldap.Conn

func Setup() {
	//fmt.Println(config.Get().Ldap)
	if !config.Get().Ldap.Enabled {
		return
	}
	fmt.Println("start to init ldap ...")
	username := config.Get().Ldap.Username
	password := config.Get().Ldap.Password
	ldapUrl := config.Get().Ldap.Url
	ldapPort := config.Get().Ldap.Port
	//DN 		 = config.Get().Ldap.BaseDN

	fmt.Printf("%v, %s\n", ldapUrl, ldapPort)
	var err error
	conn, err = ldap.DialURL(fmt.Sprintf("ldap://%s:%s", ldapUrl, ldapPort))
	if err != nil {
		log.Fatal("connect err:", err)
	}
	//defer conn.Close()
	conn.Debug.Enable(false)
	err = conn.Bind(username, password)
	if err != nil {
		log.Fatal("bind err:", err)
		return
	}
	fmt.Printf("username: %s binding successfully!!\n", username)
}

func UserAuthentication(user, pass string) error {
	DN := config.Get().Ldap.BaseDN
	// 1. 先对用户进行搜索，是否在ldap中
	filter := fmt.Sprintf("(&(objectClass=person)(sAMAccountName=%s))", user)
	searchRequest := ldap.NewSearchRequest(
		DN,
		ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
		filter,
		//[]string{"dn", "cn", "objectClass"},
		[]string{"dn", "cn", "objectClass", "sAMAccountName", "mail", "mobile", "memberOf"},
		nil,
	)

	sr, err := conn.Search(searchRequest)
	if err != nil {
		return err
	}

	if len(sr.Entries) < 1 {
		text := fmt.Sprintf("The user[%s] doesn't exist! \n", user)
		return errors.New(text)
	}
	// 2. 进行二次bind，验证用户pass是否正确
	userDN := sr.Entries[0].DN
	fmt.Printf("userDN:%#v  password:*** \n", userDN)
	attrs := sr.Entries[0].Attributes
	fmt.Println("----------------------1-----------------------")
	for i, attr := range attrs {
		fmt.Printf("index[%d] : attr: [%s] \n", i, attr)
	}
	fmt.Println("----------------------2-----------------------")
	sr.Entries[0].Print()
	fmt.Println("----------------------3-----------------------")
	fmt.Printf("mail: %s\n", sr.Entries[0].GetAttributeValue("mail"))
	fmt.Printf("sAMAccountName: %s\n", sr.Entries[0].GetAttributeValue("sAMAccountName"))
	fmt.Printf("mobile: %s\n", sr.Entries[0].GetAttributeValue("mobile"))
	fmt.Println("----------------------4-----------------------")
	groups := sr.Entries[0].GetAttributeValues("memberOf")
	for i, group := range groups {
		fmt.Printf("index[%d] - memberOf:[%s]\n", i, group)
	}
	fmt.Println("----------------------5-----------------------")
	err = conn.Bind(userDN, pass)

	if err != nil {
		return err
	}
	fmt.Println("login successfully!")
	return nil
}
